package cn.xiaopengstack.domain.activity.service.quota;

import cn.xiaopengstack.domain.activity.model.aggregate.CreateRechangeQuotaOrderAggregate;
import cn.xiaopengstack.domain.activity.model.entity.*;
import cn.xiaopengstack.domain.activity.repository.IRaffleActivityRepository;
import cn.xiaopengstack.domain.activity.service.IRaffleActivityQuotaService;
import cn.xiaopengstack.domain.activity.service.quota.policy.IRechargePolicy;
import cn.xiaopengstack.domain.activity.service.quota.rule.chain.IActionChain;
import cn.xiaopengstack.domain.activity.service.quota.rule.factory.DefaultActivityActionChainFactory;
import cn.xiaopengstack.types.enums.ResponseCode;
import cn.xiaopengstack.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Objects;

/**
 * @author jiangyangang
 */
@Slf4j
public abstract class AbsRaffleActivityQuotaService extends RaffleActivityQuotaSupport implements IRaffleActivityQuotaService {

    protected final Map<String, IRechargePolicy> tradePolicyGroup;

    public AbsRaffleActivityQuotaService(Map<String, IRechargePolicy> tradePolicyGroup, DefaultActivityActionChainFactory defaultActivityActionChainFactory, IRaffleActivityRepository activityRepository) {
        super(activityRepository, defaultActivityActionChainFactory);
        this.tradePolicyGroup = tradePolicyGroup;
    }

    @Override
    public SkuRechargeUnpaidOrderEntity createOrder(ActivitySkuRechargeEntity rechargeEntity) {
        // 查询活动
        RaffleActivitySkuEntity activitySku = queryActivitySku(rechargeEntity.getSku());
        assert Objects.nonNull(activitySku);
        // 查询SKU信息
        RaffleActivityEntity activityEntity = queryRaffleActivityByActivityId(activitySku.getActivityId());
        assert Objects.nonNull(activityEntity);
        // 查询活动次数信息
        RaffleActivityCountEntity activityCountEntity = queryRaffleActivityCountByActivityCountId(activitySku.getActivityCountId());
        // 查询用户活动账户信息
        RaffleActivityAccountEntity activityAccount = queryActivityAccount(activityEntity.getActivityId(), rechargeEntity.getUser().getUserId());
        IActionChain basicActionChain = defaultActivityActionChainFactory.buildCreateOrderChain();

        boolean checkResult = basicActionChain.doChain(ActionRuleMatterEntity.builder()
                .activityCount(activityCountEntity)
                .user(rechargeEntity.getUser())
                .activity(activityEntity)
                .activitySku(activitySku)
                .activityAccount(activityAccount)
                .decrNumber(1)
                .build());
        if (!checkResult) {
            throw new AppException(ResponseCode.ACTIVITY_CREATE_FAIL.getCode(), ResponseCode.ACTIVITY_CREATE_FAIL.getInfo());
        }

        // 创建聚合对象
        CreateRechangeQuotaOrderAggregate createOrderAggregate = buildOrderAggregate(rechargeEntity, activitySku, activityEntity, activityCountEntity);

        // 执行充值
        IRechargePolicy rechargePolicy = tradePolicyGroup.get(rechargeEntity.getRechangeTypeVO().getCode());
        rechargePolicy.doRechange(createOrderAggregate);

        return SkuRechargeUnpaidOrderEntity.builder()
                .payAmount(createOrderAggregate.getRaffleActivityOrderEntity().getPayAmount())
                .userId(rechargeEntity.getUser().getUserId())
                .outBusinessNo(createOrderAggregate.getRaffleActivityOrderEntity().getOutBusinessNo())
                .orderId(createOrderAggregate.getRaffleActivityOrderEntity().getOrderId()).build();
    }

    /**
     * 创建聚合层
     * @param skuRechargeEntity
     * @param activitySkuEntity
     * @param activityEntity
     * @param activityCountEntity
     * @return 聚合对象
     */
    protected abstract CreateRechangeQuotaOrderAggregate buildOrderAggregate(ActivitySkuRechargeEntity skuRechargeEntity,
                                                                             RaffleActivitySkuEntity activitySkuEntity,
                                                                             RaffleActivityEntity activityEntity,
                                                                             RaffleActivityCountEntity activityCountEntity);

//    /**
//     * 保存活动订单
//     * @param createOrderAggregate
//     */
//    protected abstract void doSaveOrder(CreateRechangeQuotaOrderAggregate createOrderAggregate);
}
